/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package io.simple.core.handlers;

/**
 *
 * @author rehak
 */
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import com.google.protobuf.Message;
import injections.annotations.Property;
import io.simple.core.RequestContext;
import io.simple.core.chain.RequestHandler;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;

/**
 * @author Tom
 */
public abstract class GPBJSONOutgoingHandler<OUT extends Message> implements RequestHandler {

    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(GPBJSONOutgoingHandler.class);
    private AtomicLong encodeException = new AtomicLong(0);
    private AtomicLong processException = new AtomicLong(0);
    @Property
    private String pattern;
    @Property(optional = true)
    private int patternFlags = 0;

    public GPBJSONOutgoingHandler(String pattern) {
        this.pattern = pattern;
    }

    public GPBJSONOutgoingHandler() {

    }

    @Override
    public ByteBuffer processRequest(RequestContext context, ByteBuffer data) throws Exception {
        OUT out;
        ByteBuffer outBuf;
        try {
            out = process(context, data);
        } catch (Exception e) {
            LOGGER.error("Error in handler!", e);
            processException.incrementAndGet();
            throw e;
        }
        try {
            outBuf = MessageDecoder.encodeResponse(out, context);
        } catch (Exception e) {
            LOGGER.error("Error encoding response from handler!", e);
            encodeException.incrementAndGet();
            throw e;
        }
        return outBuf;
    }

    @Override
    public Pattern getPath() {
        if (patternFlags == 0) {
            return Pattern.compile(pattern);
        } else {
            return Pattern.compile(pattern, patternFlags);
        }
    }

    public abstract OUT process(RequestContext context, ByteBuffer data) throws Exception;
}
